{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fead49e87f357db",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:06:11.835351Z",
     "start_time": "2025-08-18T07:06:11.833008Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"HF_ENDPOINT\"] = \"https://hf-mirror.com\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "initial_id",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:06:14.255492Z",
     "start_time": "2025-08-18T07:06:13.643104Z"
    },
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from dotenv import load_dotenv\n",
    "load_dotenv()\n",
    "import getpass\n",
    "import os\n",
    "\n",
    "if not os.environ.get(\"DEEPSEEK_API_KEY\"):\n",
    "  os.environ[\"DEEPSEEK_API_KEY\"] = getpass.getpass(\"Enter API key for Google Gemini: \")\n",
    "\n",
    "from langchain.chat_models import init_chat_model\n",
    "\n",
    "llm = init_chat_model(\"deepseek-chat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b657a345d5885178",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:06:26.450466Z",
     "start_time": "2025-08-18T07:06:16.442882Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"HF_ENDPOINT\"] = \"https://hf-mirror.com\"\n",
    "from langchain_huggingface import HuggingFaceEmbeddings\n",
    "\n",
    "# embeddings = HuggingFaceEmbeddings(model_name=\"sentence-transformers/all-mpnet-base-v2\")\n",
    "embeddings = HuggingFaceEmbeddings(model_name=\"Qwen/Qwen3-Embedding-0.6B\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f9bac6aa1522bd1",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:04:14.107678Z",
     "start_time": "2025-08-18T07:04:13.292429Z"
    }
   },
   "outputs": [],
   "source": [
    "\n",
    "from sentence_transformers import SentenceTransformer\n",
    "\n",
    "# Load the model\n",
    "model = SentenceTransformer(\"Qwen/Qwen3-Embedding-0.6B\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7afb04ae4cd1289",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:06:34.384860Z",
     "start_time": "2025-08-18T07:06:34.358281Z"
    }
   },
   "outputs": [],
   "source": [
    "from langchain_core.vectorstores import InMemoryVectorStore\n",
    "\n",
    "vector_store = InMemoryVectorStore(embeddings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e47f990852948dec",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-18T07:15:37.900065Z",
     "start_time": "2025-08-18T07:15:37.292331Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Document(metadata={'source': 'https://blog.csdn.net/python12222_/article/details/145327194'}, page_content='')]\n"
     ]
    }
   ],
   "source": [
    "import bs4\n",
    "from langchain import hub\n",
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "from langchain_core.documents import Document\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "from langgraph.graph import START, StateGraph\n",
    "from typing_extensions import List, TypedDict\n",
    "\n",
    "# Load and chunk contents of the blog\n",
    "loader = WebBaseLoader(\n",
    "    web_paths=(\"https://blog.csdn.net/python12222_/article/details/145327194\",),\n",
    "    bs_kwargs=dict(\n",
    "        parse_only=bs4.SoupStrainer(\n",
    "            class_=(\"post-content\", \"post-title\", \"post-header\",\"blog-content-box\")\n",
    "        )\n",
    "    ),\n",
    ")\n",
    "docs = loader.load()\n",
    "print(docs)\n",
    "text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)\n",
    "all_splits = text_splitter.split_documents(docs)\n",
    "\n",
    "# Index chunks\n",
    "_ = vector_store.add_documents(documents=all_splits)\n",
    "\n",
    "# Define prompt for question-answering\n",
    "# N.B. for non-US LangSmith endpoints, you may need to specify\n",
    "# api_url=\"https://api.smith.langchain.com\" in hub.pull.\n",
    "prompt = hub.pull(\"rlm/rag-prompt\", api_url=\"https://api.smith.langchain.com\")\n",
    "\n",
    "\n",
    "# Define state for application\n",
    "class State(TypedDict):\n",
    "    question: str\n",
    "    context: List[Document]\n",
    "    answer: str\n",
    "\n",
    "\n",
    "# Define application steps\n",
    "def retrieve(state: State):\n",
    "    retrieved_docs = vector_store.similarity_search(state[\"question\"])\n",
    "    return {\"context\": retrieved_docs}\n",
    "\n",
    "\n",
    "def generate(state: State):\n",
    "    docs_content = \"\\n\\n\".join(doc.page_content for doc in state[\"context\"])\n",
    "    messages = prompt.invoke({\"question\": state[\"question\"], \"context\": docs_content})\n",
    "    response = llm.invoke(messages)\n",
    "    return {\"answer\": response.content}\n",
    "\n",
    "\n",
    "# Compile application and test\n",
    "graph_builder = StateGraph(State).add_sequence([retrieve, generate])\n",
    "graph_builder.add_edge(START, \"retrieve\")\n",
    "graph = graph_builder.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7a2f5d880aaf31da",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "向量检索是一种通过计算向量之间的相似度来快速查找和匹配数据的技术。它常用于处理高维数据，如图像、文本或音频，通过将数据转换为向量表示并进行高效检索。这种方法广泛应用于推荐系统、搜索引擎和机器学习等领域。\n"
     ]
    }
   ],
   "source": [
    "response = graph.invoke({\"question\": \"什么是向量检索?\"})\n",
    "print(response[\"answer\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "2b94a68f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n"
     ]
    },
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mIndexError\u001b[39m                                Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[17]\u001b[39m\u001b[32m, line 3\u001b[39m\n\u001b[32m      1\u001b[39m results = vector_store.similarity_search(\u001b[33m\"\u001b[39m\u001b[33m什么是向量检索?\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m      2\u001b[39m \u001b[38;5;28mprint\u001b[39m(results)\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m \u001b[38;5;28mprint\u001b[39m(results[\u001b[32m0\u001b[39m])\n",
      "\u001b[31mIndexError\u001b[39m: list index out of range"
     ]
    }
   ],
   "source": [
    "results = vector_store.similarity_search(\"什么是向量检索?\")\n",
    "print(results)\n",
    "print(results[0])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
